<template>
  <div class="app-container">
    <div class="tabs">
      <div v-for="item in alarmRules" :key="item.value" class="tabs-item" :class="{ active: activeAlarm == item.value }"
        @click="tabChange(item.value)" v-hasPermi="['comlbs:alarmRule:' + item.show]">{{ item.name }}</div>
    </div>
    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item :label="v.name" :prop="v.prop" v-for="v in searchItems">
        <el-input v-if="v.type == 'input'" v-model="queryParams[v.prop]" :placeholder="'请输入' + v.name" clearable
          @keyup.enter="handleQuery" />
        <el-tree-select v-else-if="v.type == 'treeSelect'" v-model="queryParams[v.prop]" :placeholder="'请选择' + v.name"
          clearable :data="sel_option[v.prop]" :expand-on-click-node="false" :render-after-expand="false"
          @change="handleQuery" check-strictly :props="{ label: 'label' }" node-key="id" filterable />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="Plus" @click="handleAdd"
          v-hasPermi="['comlbs:alarmRule:add']">新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['comlbs:alarmRule:remove']">删除</el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table highlight-current-row v-loading="loading" :data="alarmRuleList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="left" />
      <el-table-column :label="v.name" align="left" :prop="v.prop" v-for="v in tableItems" :width="v.width">
        <template #default="scope">
          <dict-tag v-if="v.type == 'dict'" :options="sel_option[v.option]" :value="scope.row[v.prop]" />
          <span v-else>{{ scope.row[v.prop] }}</span>
        </template>
      </el-table-column>
      <el-table-column width="320" label="操作" align="left" class-name="small-padding fixed-width">
        <template #default="scope">
          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
            v-hasPermi="['comlbs:alarmRule:edit']">修改</el-button>
          <el-button link type="primary" @click="handleClick(scope.row, 'fence')"
            v-if="scope.row.ruleType == 1 || scope.row.ruleType == 3"
            v-hasPermi="['comlbs:alarmRule:graphSelect']">围栏选择</el-button>
          <el-button link type="primary" @click="handleClick(scope.row, 'road')"
            v-if="scope.row.ruleType == 2 || scope.row.ruleType == 4 || scope.row.ruleType == 5"
            v-hasPermi="['comlbs:alarmRule:graphSelect']">线路选择</el-button>
          <el-button link type="primary" @click="handleClick(scope.row, 'bindCar')"
            v-hasPermi="['comlbs:alarmRule:bindCar']">绑定监管对象</el-button>
          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
            v-hasPermi="['comlbs:alarmRule:remove']">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
      @pagination="getList" />

    <!-- 添加或修改指令配置对话框 -->
    <el-dialog :title="title" v-model="open" width="800px" append-to-body>
      <el-form ref="alarmRuleRef" :model="form" :rules="rules" label-width="100px" :inline="true">
        <el-form-item v-for="v in updateItem" :key="v.prop" :label="v.name" :prop="v.prop">
          <el-input v-if="v.type == 'input'" v-model.trim="form[v.prop]"></el-input>
          <el-tree-select v-else-if="v.type == 'treeSelect'" v-model="form[v.prop]" clearable :data="sel_option[v.prop]"
            :expand-on-click-node="false" :render-after-expand="false" check-strictly :props="{ label: 'label' }"
            node-key="id" filterable placeholder="" />
        </el-form-item>
        <!-- 围栏报警 -->
        <el-form-item label="规则属性" prop="pageTag" v-if="activeAlarm == 1" class="ruleProp">
          <span class="required">*</span>
          <div class="form_input">
            <el-radio-group v-model="form.pageTag">
              <el-radio :label="v.prop" v-for="v in sel_option.fenceList" :key="v.prop">{{ v.value }}</el-radio>
            </el-radio-group>
          </div>
        </el-form-item>
        <!-- 超速  路段限速 -->
        <el-form-item label="规则属性" prop="speedLimit" v-else-if="activeAlarm == 3 || activeAlarm == 4" class="ruleProp">
          <span class="required">*</span>
          <div class="form_input">
            <span>超速阈值</span><input type="text" class="inputClass"
              v-model="jsonObj.speedLimit" /><span>km/h，持续时间</span><input type="text" class="inputClass"
              v-model="jsonObj.overspeedTime" />s
          </div>
        </el-form-item>
        <!-- 路线偏移 -->
        <el-form-item label="规则属性" prop="tyroadOffsetpe" v-else-if="activeAlarm == 2 || activeAlarm == 5"
          class="ruleProp">
          <span class="required">*</span>
          <div class="form_input">
            <span>偏移量</span><input type="text" class="inputClass" v-model="jsonObj.roadOffset" />米
          </div>
        </el-form-item>
        <div class="time_Attr" v-for="(item, i) in jsonObj.timeAttr" :key="i">
          <div>
            <el-form-item>
              <template #label>
                有效日期
              </template>
              <span class="required" v-if="i == 0">*</span>
              <el-date-picker style="width:220px" v-model="item.date" type="daterange" range-separator="至"
                start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" />
              <span class="addIcon" @click="handleDate(i)">
                <el-icon>
                  <CirclePlusFilled v-if="i == 0" />
                  <RemoveFilled v-else />
                </el-icon>
              </span>
            </el-form-item>
          </div>
          <div style="width:380px;">
            <el-form-item label="有效时间范围" v-for="(v, ii) in item.time" :key="ii">
              <span class="required" style="left:-105px" v-if="i == 0 && ii == 0">*</span>
              <el-time-picker style="width:220px" is-range v-model="v.timeRange" range-separator="至"
                start-placeholder="开始时间" end-placeholder="结束时间" placeholder="" value-format="HH:mm:ss" />
              <span class="addIcon" @click="handleTime(i, ii)">
                <el-icon>
                  <CirclePlusFilled v-if="ii == 0" />
                  <RemoveFilled v-else />
                </el-icon>
              </span>
            </el-form-item>
          </div>
        </div>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 围栏选择/线路选择 -->
    <el-dialog :title="title" v-model="fenceOrLineOpen" width="800px" append-to-body>
      <fenceBind v-if="fenceOrLineOpen" ref="fenceOrLineBind" style="height: 450px;position: relative;"
        :fenceOrLineTable="fenceOrLineTable" :parentQuery="fenceOrLineQuery" :companyOptions="sel_option.companyId">
      </fenceBind>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="fenceOrLineSave">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 围栏选择/线路选择 -->
    <el-dialog :title="title" v-model="dialogCarBindOpen" width="1000px" append-to-body>
      <select-bind v-if="dialogCarBindOpen" ref="carBind" style="height:450px" :treeList="sel_option.companyId"
        :alarmRuleId="alarmRuleId" :bindTableHeader="bindTableHeader" :chkCarIdList="chkCarIdList"></select-bind>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="carBindSave">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="AlarmRule">
import { listAlarmRule, delAlarmRule, addAlarmRule, updateAlarmRule, savefenceOrLine, saveCarData } from "@/api/comlbs/alarmRule";
import { treeDept } from "@/api/system/dept";
import fenceBind from "./fenceBind"
import selectBind from "./carBind"

const { proxy } = getCurrentInstance();

const alarmRuleList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);

const fenceOrLineBind = ref(null)  // 围栏/线路子组件ref
const fenceOrLineOpen = ref(false);  // 围栏/线路弹框
const fenceOrLineQuery = ref({});  // 围栏/线路弹框-查询参数
const fenceOrLineTable = ref([
  { name: "name", label: "围栏名称" },
  { name: "companyName", label: "所属公司", width: 220 },
  { name: "createUserName", label: "创建人" },
  { name: "createTime", label: "创建时间", width: 200 },
]);  // 围栏/线路弹框-tableItem

const carBind = ref(null) // 绑定监管对象子组件ref
const dialogCarBindOpen = ref(false) // 绑定监管对象弹框
const alarmRuleId = ref('')
const chkCarIdList = ref([]) // 已选中设备 id
const bindTableHeader = ref([
  { key: "checkbox", width: 50 },
  { key: "numberPlate", title: "设备名称", width: 200 },
  { key: "companyName", title: "所属公司", width: null },
])

const title = ref("");
const activeAlarm = ref(1);
const alarmRules = ref([
  { name: '围栏报警', value: 1, show: 'fenceAlarm' },//line
  { name: '线路偏移', value: 2, show: 'lineOffset' },//polygon
  { name: '超速规则', value: 3, show: 'overspeed' },//polygon
  { name: '路段限速', value: 4, show: 'speedLimit' },//line
  { name: '线路禁入', value: 5, show: 'lineDebar' },//line
]);
const jsonObj = ref({
  timeAttr: [
    {
      date: '',
      time: [
        {
          timeRange: ''
        },
      ],
    },
  ],
})

const data = reactive({
  form: {},
  queryParams: {
    pageNum: 1,
    pageSize: 15,
    companyId: null,
    ruleType: null,
    name: null
  },
  rules: {
    name: [
      { required: true, message: "请输入规则名称", trigger: "blur" },
      { required: true, message: "请输入规则名称", trigger: "change" },
    ],
    companyId: [
      { required: true, message: "请选择所属公司", trigger: "input" },
    ]
  }
});
const searchItems = ref([
  { name: '规则名称', prop: "name", type: 'input' },
  { name: '所属公司', prop: "companyId", type: 'treeSelect' },
]);
const tableItems = ref([
  { name: '规则名称', prop: "name" },
  { name: '规则属性', prop: "ruleAttr" },
  { name: '所属公司', prop: "companyName" },
  { name: '创建时间', prop: "createTime" },
])
const updateItem = ref([
  { name: '所属公司', prop: 'companyId', type: 'treeSelect' },
  { name: '规则名称', prop: 'name', type: 'input' },
])
const sel_option = ref({
  fenceList: [
    { prop: "banInRule", value: "进围栏报警" },
    { prop: "banOutRule", value: "出围栏报警" },
    { prop: "banInOutRule", value: "进出围栏报警" },
  ],
});
const { queryParams, form, rules } = toRefs(data);
treeDept().then(res => {
  sel_option.value.companyId = res.data
})

function handleDate(index) {
  if (index == 0) {
    jsonObj.value.timeAttr.push(
      {
        date: '',
        time: [
          {
            timeRange: ''
          },
        ],
      }
    )
  } else {
    jsonObj.value.timeAttr.splice(index, 1)
  }
}
function handleTime(i, secondIndex) {
  if (secondIndex == 0) {
    jsonObj.value.timeAttr[i].time.push(
      {
        timeRange: ''
      },
    )
  } else {
    jsonObj.value.timeAttr[i].time.splice(secondIndex, 1)
  }
}

/** 查询指令配置列表 */
function getList() {
  loading.value = true;
  queryParams.value.ruleType = activeAlarm.value;
  listAlarmRule(queryParams.value).then(response => {
    alarmRuleList.value = response.rows;
    total.value = Number(response.total);
    loading.value = false;
  });
}

// 取消按钮
function cancel() {
  open.value = false;
  fenceOrLineOpen.value = false;
  dialogCarBindOpen.value = false;
  reset();
}

// 表单重置
function reset() {
  form.value = {
    id: null,
    companyId: null,
    name: null,
    ruleType: null,
    pageTag: null,
    ruleAttr: null,
    confValue: null,
    gmtCreate: null,
    gmtModified: null
  };
  proxy.resetForm("alarmRuleRef");
}

/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}

/** 重置按钮操作 */
function resetQuery() {
  proxy.resetForm("queryRef");
  handleQuery();
}

function tabChange(index) {
  activeAlarm.value = index
  getList();
}

// 多选框选中数据
function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.id);
  single.value = selection.length != 1;
  multiple.value = !selection.length;
}

/** 新增按钮操作 */
function handleAdd() {
  reset();
  jsonObj.value = {
    timeAttr: [
      {
        date: '',
        time: [
          {
            timeRange: ''
          },
        ],
      },
    ],
  };
  open.value = true;
  title.value = "添加规则配置";
}

/** 修改按钮操作 */
function handleUpdate(row) {
  reset();
  form.value = { ...row };
  jsonObj.value = row.confValue;
  open.value = true;
  title.value = "修改规则配置";
}
// 报警规则提交参数封装
function setParamData() {
  let isEmpty = false; //必填项规则属性判空
  let isNum = true, text = ''; //规则属性格式判断
  let MyRegExp = /^((0{1}\.\d*)|([1-9]\d*\.{1}\d*)|([1-9]+\d*))$/
  let _timeAttr = jsonObj.value.timeAttr;
  switch (activeAlarm.value) {
    case 1://围栏
      form.value.ruleAttr = sel_option.value.fenceList.filter(v => {
        return form.value.pageTag === v.prop
      })[0]?.value
      if (!form.value.pageTag) {
        isEmpty = true
      }
      break
    case 2://线路偏移
    case 5://线路禁入
      form.value.ruleAttr = "偏移量" + jsonObj.value.roadOffset + "米"
      if (!jsonObj.value.roadOffset) {
        isEmpty = true
      }
      if (!MyRegExp.test(jsonObj.value.roadOffset)) {
        isNum = false
        text = '偏移量只能为正数'
      }
      form.value.pageTag = activeAlarm.value == 2 ? "roadOffset" : "roadBanIn";
      break
    case 3://超速规则
    case 4://路段限速
      form.value.ruleAttr = "超速阈值" + jsonObj.value.speedLimit + "km/h，持续时间" + jsonObj.value.overspeedTime + "s"
      if (!jsonObj.value.speedLimit || !jsonObj.value.overspeedTime) {
        isEmpty = true
      }
      if (!MyRegExp.test(jsonObj.value.speedLimit) || !MyRegExp.test(jsonObj.value.overspeedTime)) {
        isNum = false
        text = '超速阈值和持续时间只能为正数'
      }
      form.value.pageTag = activeAlarm.value == 3 ? "speedingRule" : "roadSpdLimit";
      break
  }
  function judgeCallBack(_bool, _content) {
    if (_bool) {
      proxy.$modal.notify({
        message: _content,
        type: "error",
        position: "bottom-right",
        duration: 2000,
      });
    }
    return _bool
  }
  if (judgeCallBack(isEmpty, "请填写规则属性")) return
  if (judgeCallBack(!isNum, text)) return
  if (judgeCallBack(!_timeAttr[0].date || !_timeAttr[0].time[0].timeRange, "请填写有效期和有效范围")) return
}
/** 提交按钮 */
function submitForm() {
  setParamData()
  form.value.ruleType = activeAlarm.value;
  form.value.confValue = jsonObj.value
  proxy.$refs["alarmRuleRef"].validate(valid => {
    if (valid) {
      if (form.value.id != null) {
        updateAlarmRule(form.value).then(response => {
          proxy.$modal.msgSuccess("修改成功");
          open.value = false;
          getList();
        });
      } else {
        addAlarmRule(form.value).then(response => {
          proxy.$modal.msgSuccess("新增成功");
          open.value = false;
          getList();
        });
      }
    }
  });
}

// 围栏选择 线路选择 绑定监管对象 点击操作（row行数据，obj操作对象）
function handleClick(row, obj) {
  switch (obj) {
    case "fence":
    case "road":
      fenceOrLineQuery.value = {
        alarmRuleId: row.id
      };
      fenceOrLineOpen.value = true;
      if (obj == "fence") {
        fenceOrLineTable.value[0].label = "围栏名称"
        title.value = "围栏选择"
        fenceOrLineQuery.value.type = 2
      } else {
        fenceOrLineTable.value[0].label = "线路名称"
        title.value = "线路选择"
        fenceOrLineQuery.value.type = 3
      }
      break
    case "bindCar":
      title.value = "绑定监管对象"
      dialogCarBindOpen.value = true;
      alarmRuleId.value = row.id;
      break
  }
}
// 绑定围栏/线路
function fenceOrLineSave() {
  let _data = {
    alarmRuleId: fenceOrLineQuery.value.alarmRuleId,
    newBindIds: fenceOrLineBind.value.newList,
  }

  let hash = {};
  fenceOrLineBind.value.oldSelList.forEach(vv => {
    hash[vv.id] = true;
  })
  _data.unbindIds = fenceOrLineBind.value.initialList.filter(v => { //解绑
    return !hash[v]
  });
  savefenceOrLine(_data).then(res => {
    if (res.code == 200) {
      proxy.$modal.msgSuccess("操作成功");
      fenceOrLineOpen.value = false;
    }
  })
}
// 绑定监管对象
function carBindSave() {
  // 当前勾选的数据_nowSelectedId  初始勾选的数据carBind.value.initialList
  let _nowSelectedId = [], _newBindIds = [], _unbindIds = []
  carBind.value.selectTableData.forEach(v => {
    if (v.checkStatus) _nowSelectedId.push(v.objectId)
  })
  // 新勾选的数据
  _newBindIds = _nowSelectedId.filter(el => {
    let isAdd = true //是否为新勾选的数据
    carBind.value.initialList.forEach(v => {  //当前勾选的数据中能找到初始数据 说明不是新勾选的数据 置为false
      if (v == el) isAdd = false
    })
    return isAdd
  })
  // 取消勾选的数据
  _unbindIds = carBind.value.initialList.filter(el => {
    let isDel = true //是否为新勾选的数据
    _nowSelectedId.forEach(v => {  //初始数据中能找到当前勾选的数据 说明不是取消勾选的数据 置为false
      if (v == el) isDel = false
    })
    return isDel
  })

  let _data = {
    alarmRuleId: alarmRuleId.value,
    newBindIds: _newBindIds,
    unbindIds: _unbindIds
  }
  saveCarData(_data).then(res => {
    if (res.code == 200) {
      proxy.$modal.msgSuccess("操作成功");
      dialogCarBindOpen.value = false;
    }
  })
}
/** 删除按钮操作 */
function handleDelete(row) {
  const _ids = row.id || ids.value;
  let length = row.id ? 1 : _ids.length
  proxy.$modal.confirm('是否确认删除这' + length + '项数据？').then(function () {
    return delAlarmRule(_ids);
  }).then(() => {
    getList();
    proxy.$modal.msgSuccess("删除成功");
  }).catch(() => { });
}

getList();
</script>
<style lang='scss' scoped>
.tabs {
  width: 100%;
  height: 50px;
  color: #6B7A99;
  font-size: 16px;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  background: #fff;

  .tabs-item {
    padding: 14px 32px;
    cursor: pointer;
  }

  .active {
    color: var(--el-color-primary);
    font-weight: 500;
    border-bottom: 2px var(--el-color-primary) solid;
  }
}

.ruleProp {
  width: 100%;
}

.time_Attr {
  margin-bottom: 20px;
  background-color: rgb(242, 247, 255);
  padding: 10px 0;
  display: flex;

  .addIcon {
    position: absolute;
    top: 4px;
    right: -25px;
    font-size: 24px;
    cursor: pointer;
    color: #0066ff;
  }
}

.form_input {
  width: 400px;

  .inputClass {
    margin: 0 10px;
    width: 50px;
    padding: 0 5px;
    height: 32px;
    border-radius: 8px;
    border: 1px solid #dadada;
    outline: none;
  }
}

.required {
  color: #f56c6c;
  left: -78px;
  position: absolute;
}
</style>